package com.spark.common.exception.handler;

import com.spark.common.core.Result;
import com.spark.common.exception.Spark401Exception;
import com.spark.common.exception.SparkException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MaxUploadSizeExceededException;

import java.sql.SQLSyntaxErrorException;

/**
 * 全局异常处理器
 *
 * @author LYCHEE
 * @date 2025/2/14 14:50
 */
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 处理自定义异常
     *
     * @param e 异常
     * @return 错误信息
     */
    @ExceptionHandler(SparkException.class)
    @ResponseBody
    public Result<?> handleSparkException(SparkException e) {
        log.error("捕获到自定义异常,异常信息：{}", e.getMessage(), e);
        return Result.fail(e.getMessage());
    }

    /**
     * 处理无权限自定义异常
     *
     * @param e 异常
     * @return 错误信息
     */
    @ExceptionHandler(Spark401Exception.class)
    @ResponseBody
    public Result<?> handleSpark401Exception(Spark401Exception e) {
        log.error("捕获到无权限异常,异常信息：{}", e.getMessage(), e);
        return Result.fail(e.getMessage());
    }

    /**
     * 处理文件或请求大小超过限制异常
     *
     * @param e 异常
     * @return 错误信息
     */
    @ExceptionHandler(MaxUploadSizeExceededException.class)
    @ResponseBody
    public Result<?> handleMaxUploadSizeExceededException(MaxUploadSizeExceededException e) {
        log.error("捕获到文件大小或请求大小超过限制异常,异常信息：{}", e.getMessage(), e);
        return Result.fail("文件大小或请求超过最大限制");
    }

    /**
     * 处理RequestParam参数为空
     *
     * @param e 异常
     * @return 错误信息
     */
    @ExceptionHandler(MissingServletRequestParameterException.class)
    @ResponseBody
    public Result<?> handleMissingServletRequestParameterException(MissingServletRequestParameterException e) {
        log.error("捕获到RequestParam参数为空异常,异常信息：{}", e.getMessage(), e);
        return Result.fail(e.getMessage());
    }

    /**
     * Post请求没有请求体
     * @param e 异常
     * @return 错误信息
     */
    @ExceptionHandler(HttpMessageNotReadableException.class)
    @ResponseBody
    public Result<?> handleHttpMessageNotReadableException(HttpMessageNotReadableException e){
        log.error("捕获到Post请求没有请求体异常,异常信息：{}", e.getMessage(), e);
        return Result.fail("非法请求");
    }

    /**
     * 处理请求方法不对异常
     *
     * @param e 异常
     * @return 错误信息
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    @ResponseBody
    public Result<?> handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
        log.error("捕获到处理请求方法不对异常,异常信息：{}", e.getMessage(), e);
        StringBuilder builder = new StringBuilder();
        builder.append("该请求不支持：").append(e.getMethod()).append("请求；支持以下请求方式：");
        String[] methods = e.getSupportedMethods();
        if (methods != null) {
            for (String str : methods) {
                builder.append(str);
                builder.append("、");
            }
        }
        String msg = builder.substring(0, builder.toString().length() - 1);
        return Result.fail(msg);
    }

    /**
     * 处理@Valid实体检验字段异常
     * @param e 异常
     * @return
     */
    @ExceptionHandler(BindException.class)
    @ResponseBody
    public Result<?> handleValidationExceptions(BindException e) {
        StringBuilder errorMessage = new StringBuilder();
        // 获取 BindingResult，其中包含了验证错误的详细信息
        e.getBindingResult().getAllErrors().forEach(error -> {
            // 获取错误的默认消息
            String defaultMessage = error.getDefaultMessage();
            // 将每个错误的默认消息添加到 StringBuilder 中
            errorMessage.append(defaultMessage).append("、");
        });
        String msg = errorMessage.substring(0, errorMessage.toString().length() - 1);
        log.error("参数检验异常: {}",msg);
        return Result.fail(msg.split("、")[0]);
    }

    /**
     * SQL拼写异常
     * @param e 异常
     * @return 错误信息
     */
    @ExceptionHandler(SQLSyntaxErrorException.class)
    @ResponseBody
    public Result<?> handleSQLSyntaxErrorException(SQLSyntaxErrorException e){
        log.error("SQL拼写异常,异常信息：{}", e.getMessage(), e);
        return Result.fail("SQL拼写异常：" + e.getMessage());
    }
}
